package com.invengo.library_db;

import android.annotation.SuppressLint;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.text.TextUtils;
import android.util.Log;

import com.blankj.utilcode.util.TimeUtils;
import com.invengo.library_db.dao.BookBeanDao;
import com.invengo.library_db.dao.BookCarBeanDao;
import com.invengo.library_db.dao.ColumBeanDao;
import com.invengo.library_db.dao.DaoMaster;
import com.invengo.library_db.dao.DaoSession;
import com.invengo.library_db.dao.FlowBeanDao;
import com.invengo.library_db.dao.ShelfBeanDao;
import com.invengo.library_db.dao.StructBeanDao;
import com.invengo.library_db.dao.UserBeanDao;
import com.invengo.library_db.entity.module_check.BookBean;
import com.invengo.library_db.entity.module_check.BookCarBean;
import com.invengo.library_db.entity.module_check.ColumBean;
import com.invengo.library_db.entity.module_check.offline.FlowBean;
import com.invengo.library_db.entity.module_check.offline.FlowType;
import com.invengo.library_db.entity.module_check.ShelfBean;
import com.invengo.library_db.entity.module_check.offline.UserBean;
import com.invengo.library_db.entity.module_check.StructBean;

import org.greenrobot.greendao.query.WhereCondition;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import java8.util.J8Arrays;
import java8.util.stream.StreamSupport;
import me.goldze.mvvmhabit.http.UpdateResult;
import me.goldze.mvvmhabit.http.interceptor.logging.LocalLogUtil;
import me.goldze.mvvmhabit.utils.KLog;
import me.goldze.mvvmhabit.utils.cache.ACache;
import me.goldze.mvvmhabit.utils.cache.AKey;

public class GreenDaoManager {
    private static GreenDaoManager instance;
    private DaoMaster.DevOpenHelper devOpenHelper;
    private DaoMaster daoMaster;
    private DaoSession daoSession;

    private GreenDaoManager() {
    }

    public static GreenDaoManager getInstance() {
        if (instance == null) {
            synchronized (GreenDaoManager.class) {
                if (instance == null) {
                    instance = new GreenDaoManager();
                }
            }
        }
        return instance;
    }

    public void setDataBase(Context context) {
        devOpenHelper = new DaoMaster.DevOpenHelper(context, "invengo-db", null);
        SQLiteDatabase writableDatabase = devOpenHelper.getWritableDatabase();
//        Database database = devOpenHelper.getWritableDb();
        daoMaster = new DaoMaster(writableDatabase);
        daoSession = daoMaster.newSession();

    }


    public void dropIndex() {
        new Thread(() -> {
            try {
                List<String> bookIndex = getBookIndex();
                for (String index : bookIndex) {
                    daoSession.getDatabase().execSQL("drop index " + index);
                }
                System.out.println("----------删除完成：------------");
                getBookIndex();
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }).start();
    }

    public void createNewIndex() {
        System.out.println("----------创建之前：------------");
        List<String> bookIndex1 = getBookIndex();
        long start = System.currentTimeMillis();
        if (!bookIndex1.contains("IDX_BOOK_BEAN__id")) {
            daoSession.getDatabase().execSQL("create index IDX_BOOK_BEAN__id on BOOK_BEAN(_id)");
        }
        if (!bookIndex1.contains("IDX_BOOK_BEAN_TID")) {
            daoSession.getDatabase().execSQL("create index IDX_BOOK_BEAN_TID on BOOK_BEAN(TID)");
        }
        if (!bookIndex1.contains("IDX_BOOK_BEAN_BAR_CODE")) {
            daoSession.getDatabase().execSQL("create index IDX_BOOK_BEAN_BAR_CODE on BOOK_BEAN(BAR_CODE)");
        }
        if (!bookIndex1.contains("IDX_BOOK_BEAN_SHELF_CODE")) {
            daoSession.getDatabase().execSQL("create index IDX_BOOK_BEAN_SHELF_CODE on BOOK_BEAN(SHELF_CODE)");
        }
        System.out.println(System.currentTimeMillis() - start + "----------创建之后：------------");
        getBookIndex();
    }

    private List<String> getBookIndex() {
        List<String> bookIndex = new ArrayList<>();
        Cursor cur = daoSession.getDatabase().rawQuery("SELECT NAME FROM sqlite_master WHERE type = 'index'", null);
        for (cur.moveToFirst(); !cur.isAfterLast(); cur.moveToNext()) {
            int nameColumn = cur.getColumnIndex("name");
            String name = cur.getString(nameColumn);
            System.out.println("当前索引：  " + name);
            if (name.startsWith("IDX_BOOK_BEAN"))
                bookIndex.add(name);
        }
//        bookIndex.remove("IDX_BOOK_BEAN__id");
        return bookIndex;
    }

    private DaoSession getDaoSession() {
        return daoSession;
    }

    /**
     * 按帐户查询用户
     *
     * @param account  账户
     * @param password 暗语
     * @return {@link UserBean}
     */
    public UserBean queryUserByAccount(String account, String password) {
//        KLog.e("查询数据库");
        UserBean unique = getDaoSession().getUserBeanDao().queryBuilder().where(UserBeanDao.Properties.UserName.eq(account)).where(UserBeanDao.Properties.Password.eq(password)).build().unique();
        return unique;
    }

    /**
     * 插入user2数据库
     *
     * @param users 用户
     */
    public void insertUser2DB(List<UserBean> users) {
        getDaoSession().getUserBeanDao().insertInTx(users);
    }

    public void insertBookCar(BookCarBean bean) {
        getDaoSession().getBookCarBeanDao().insertOrReplace(bean);
    }

    /**
     * 插入自身信息
     *
     * @param shelfBeans 货架信息豆
     */
    public void insertSelfInfo(List<ShelfBean> shelfBeans) {
        try {
            getDaoSession().runInTx(() -> getDaoSession().getShelfBeanDao().insertInTx(shelfBeans));
        } catch (Exception e) {
            KLog.e("xxxxxxxxx", e.toString());
            throw new RuntimeException(e);
        }
    }

    public void saveBooks2DB(List<BookBean> bookBeans) {
        try {
            getDaoSession().getBookBeanDao().insertInTx(bookBeans);
        } catch (Exception e) {
            KLog.e("xxxxxxxxx", e.toString());
            throw new RuntimeException(e);
        }
    }

    public void updateBook2DB(List<BookBean> bookBeans) {
        getDaoSession().getBookBeanDao().insertOrReplaceInTx(bookBeans);
    }

    public void updateShelf2DB(List<ShelfBean> shelfBeans) {
        getDaoSession().getShelfBeanDao().insertOrReplaceInTx(shelfBeans);
    }

    public void cleanLocalData() {
//        getDaoSession().getShelfInfoBeanDao().deleteAll();
        getDaoSession().getBookBeanDao().deleteAll();
        getDaoSession().getUserBeanDao().deleteAll();
    }

    public void cleanAllData() {
//        getDaoSession().getShelfInfoBeanDao().deleteAll();
        getDaoSession().getBookBeanDao().deleteAll();
        getDaoSession().getUserBeanDao().deleteAll();
    }

    public void cleanUserData() {
        getDaoSession().getUserBeanDao().deleteAll();
    }

    public void cleanShelfData() {
        getDaoSession().getColumBeanDao().deleteAll();
        getDaoSession().getShelfBeanDao().deleteAll();
    }

    public List<ShelfBean> getAllShelfs() {
        return getDaoSession().getShelfBeanDao().loadAll();
    }

    public void cleanBookData() {
        if (getBookCountFromDB() > 50 * 10000) {
            String sql = "select sql from sqlite_master WHERE name ='BOOK_BEAN'";
            Cursor c = daoSession.getDatabase().rawQuery(sql, new String[]{});
            String bookBeanSql = "";
            try {
                if (c != null) {
                    if (c.moveToFirst()) {
                        do {
                            bookBeanSql = c.getString(0);
                        } while (c.moveToNext());
                    }
                }
            } finally {
                if (c != null) {
                    c.close();
                }
            }
            if (TextUtils.isEmpty(bookBeanSql)) {
                getDaoSession().getBookBeanDao().deleteAll();
            } else {
                String[] dropTables = new String[]{
                        "DROP TABLE BOOK_BEAN",
                        "VACUUM",
                        bookBeanSql
                };
                for (String dropTable : dropTables) {
                    long start = System.currentTimeMillis();
                    daoSession.getDatabase().execSQL(dropTable);
                    KLog.e(dropTable.substring(0, 4) + " :" + (System.currentTimeMillis() - start));
                }
            }
        } else {
            long start = System.currentTimeMillis();
            getDaoSession().getBookBeanDao().deleteAll();
            KLog.e("手动删除 :" + (System.currentTimeMillis() - start));
        }
    }


    public Long getBookCountFromDB() {
        return getDaoSession().getBookBeanDao().queryBuilder().count();
    }

    public Long getUserCountFromDB() {
        return getDaoSession().getUserBeanDao().queryBuilder().count();
    }

    public Long getShelfCount() {
        return getDaoSession().getShelfBeanDao().queryBuilder().count();
    }

    private static final String START_LINE = "┌────── Request ────────────────────────────────────────────────────────────────────────";
    private static final String END_LINE = "└───────────────────────────────────────────────────────────────────────────────────────";
//    private static final String RESPONSE_UP_LINE = "┌────── Response ───────────────────────────────────────────────────────────────────────";


    public BookBean getBookByTid(String tid) {
        LocalLogUtil.local2File(START_LINE,"getBookByTid",tid);
        BookBean unique = getDaoSession().getBookBeanDao().queryBuilder().where(BookBeanDao.Properties.Tid.eq(tid)).unique();
        LocalLogUtil.local2File(unique==null?"查无此数据":unique.toString(),END_LINE);
        return unique;
    }

    public BookBean getBookByCode(String code) {
        LocalLogUtil.local2File(START_LINE,"getBookByCode",code);
        BookBean unique = getDaoSession().getBookBeanDao().queryBuilder().where(BookBeanDao.Properties.BarCode.eq(code)).limit(1).unique();
        LocalLogUtil.local2File(unique==null?"查无此数据":unique.toString(),END_LINE);
        return unique;
    }

    public List<BookBean> getBookByShelfCode(String shelfCode) {
        LocalLogUtil.local2File(START_LINE,"getBookByShelfCode",shelfCode);
        List<BookBean> unique = getDaoSession().getBookBeanDao().queryBuilder().where(BookBeanDao.Properties.ShelfCode.eq(shelfCode)).list();
        LocalLogUtil.local2File(unique==null?"查无此数据":unique.toString(),END_LINE);
        return unique;
    }

    public ShelfBean getShelfInfoByCode(String shelfCode) {
        LocalLogUtil.local2File(START_LINE,"getShelfInfoByCode",shelfCode);
        ShelfBean unique = getDaoSession().getShelfBeanDao().queryBuilder().where(ShelfBeanDao.Properties.ShelfCode.eq(shelfCode)).limit(1).unique();
        LocalLogUtil.local2File(unique==null?"查无此数据":unique.toString(),END_LINE);
        return unique;
    }

    public ShelfBean getShelfInfoByTid(String tid) {
        LocalLogUtil.local2File(START_LINE,"getShelfInfoByTid",tid);
        ShelfBean unique = getDaoSession().getShelfBeanDao().queryBuilder().where(ShelfBeanDao.Properties.Tid.eq(tid)).limit(1).unique();
        LocalLogUtil.local2File(unique==null?"查无此数据":unique.toString(),END_LINE);
        return unique;
    }


    public void changeBookBarCode(String barCode, String replace) {
        BookBean unique = getDaoSession().getBookBeanDao().queryBuilder().where(BookBeanDao.Properties.BarCode.eq(barCode)).unique();
        unique.setBarCode(replace);
        getDaoSession().getBookBeanDao().insertOrReplaceInTx(unique);
    }

    public ShelfBean getNextOrUpperShelf(String shelfCode, boolean isNext) {
        ShelfBean unique = getDaoSession().getShelfBeanDao().queryBuilder().where(ShelfBeanDao.Properties.ShelfCode.eq(shelfCode)).unique();
        Long newId = unique.getId() + (isNext ? -1 : 1);
        return getDaoSession().getShelfBeanDao().queryBuilder().where(ShelfBeanDao.Properties.Id.eq(newId)).unique();
    }


    public List<BookBean> getBookByKeyworkd(String keywordPattern, Integer pageSize) {
        return getDaoSession().getBookBeanDao().queryBuilder().whereOr(BookBeanDao.Properties.BarCode.like(keywordPattern),
                        BookBeanDao.Properties.BookName.like(keywordPattern),
                        BookBeanDao.Properties.CallNo.like(keywordPattern))
                .limit(pageSize).list();
    }

    public List<ShelfBean> getShelfListByShelfCode(String code) {
        List<ShelfBean> list = getDaoSession().getShelfBeanDao().queryBuilder().where(ShelfBeanDao.Properties.ShelfCode.like("%" + code + "%")).build().list();
        for (ShelfBean bean : list) {
            if (!TextUtils.isEmpty(bean.getFirstBookID())) {
                BookBean bookByCode = getBookByCode(bean.getFirstBookID());
                bean.setFirstBookName(bookByCode.getBookName());
            }
        }
        return list;
    }


    public UpdateResult cacheForceRevoke(String json, List<BookBean> bookBeans) {
        updateBook2DB(bookBeans);
        FlowBean flowBean1 = new FlowBean();
        flowBean1.setUserId((Integer) ACache.getInstance().getAsObject(AKey.CACHE_USER_STAFF_ID));
        flowBean1.setFlowType(FlowType.FLOW_FORCE_REVOKE);
        flowBean1.setDateTime(TimeUtils.getNowString());
        flowBean1.setBodyJson(json);
//        LocalLogUtil.temp2File("撤销强制定位：", flowBean1.toString());
        getDaoSession().getFlowBeanDao().insert(flowBean1);
        return new UpdateResult(bookBeans.size());
    }

    public UpdateResult cacheForcePos(String json, List<BookBean> bookBeans) {
        updateBook2DB(bookBeans);
        FlowBean flowBean1 = new FlowBean();
        flowBean1.setUserId((Integer) ACache.getInstance().getAsObject(AKey.CACHE_USER_STAFF_ID));
        flowBean1.setFlowType(FlowType.FLOW_FORCE);
        flowBean1.setDateTime(TimeUtils.getNowString());
        flowBean1.setBodyJson(json);
//        LocalLogUtil.temp2File("强制定位：", flowBean1.toString());
        getDaoSession().getFlowBeanDao().insert(flowBean1);
        return new UpdateResult(bookBeans.size());
    }

    public UpdateResult cacheBookListing(String json, List<BookBean> bookBeans) {
        updateBook2DB(bookBeans);
        FlowBean flowBean1 = new FlowBean();
        flowBean1.setUserId((Integer) ACache.getInstance().getAsObject(AKey.CACHE_USER_STAFF_ID));
        flowBean1.setFlowType(FlowType.FLOW_LISTING);
        flowBean1.setDateTime(TimeUtils.getNowString());
        flowBean1.setBodyJson(json);
//        LocalLogUtil.temp2File("上架：", flowBean1.toString());
        getDaoSession().getFlowBeanDao().insert(flowBean1);
        return new UpdateResult(bookBeans.size());
    }

    public UpdateResult cacheInventory(String json, List<BookBean> tempBookBeans) {
        updateBook2DB(tempBookBeans);
        FlowBean flowBean1 = new FlowBean();
        flowBean1.setUserId((Integer) ACache.getInstance().getAsObject(AKey.CACHE_USER_STAFF_ID));
        flowBean1.setFlowType(FlowType.FLOW_INVENTORY);
        flowBean1.setDateTime(TimeUtils.getNowString());
        flowBean1.setBodyJson(json);
//        LocalLogUtil.temp2File("盘点：", flowBean1.toString());

        getDaoSession().getFlowBeanDao().insert(flowBean1);
        return new UpdateResult(tempBookBeans.size());
    }

    public UpdateResult cacheParallel(String json, List<BookBean> tempBookBeans) {
        updateBook2DB(tempBookBeans);
        FlowBean flowBean1 = new FlowBean();
        flowBean1.setUserId((Integer) ACache.getInstance().getAsObject(AKey.CACHE_USER_STAFF_ID));
        flowBean1.setFlowType(FlowType.FLOW_PARALLEL);
        flowBean1.setDateTime(TimeUtils.getNowString());
        flowBean1.setBodyJson(json);
//        LocalLogUtil.temp2File("顺架：", flowBean1.toString());
        getDaoSession().getFlowBeanDao().insert(flowBean1);
        return new UpdateResult(tempBookBeans.size());
    }

    public UpdateResult cacheDownBooks(String json, List<BookBean> bookBeans) {
        updateBook2DB(bookBeans);
        FlowBean flowBean1 = new FlowBean();
        flowBean1.setUserId((Integer) ACache.getInstance().getAsObject(AKey.CACHE_USER_STAFF_ID));
        flowBean1.setFlowType(FlowType.FLOW_DOWN);
        flowBean1.setDateTime(TimeUtils.getNowString());
        flowBean1.setBodyJson(json);
//        LocalLogUtil.temp2File("下架：", flowBean1.toString());

        getDaoSession().getFlowBeanDao().insert(flowBean1);
        return new UpdateResult(bookBeans.size());
    }

    public UpdateResult cacheinsertBookDeleteLogs(String json, List<BookBean> bookBeans) {
        updateBook2DB(bookBeans);
        FlowBean flowBean1 = new FlowBean();
        flowBean1.setUserId((Integer) ACache.getInstance().getAsObject(AKey.CACHE_USER_STAFF_ID));
        flowBean1.setFlowType(FlowType.FLOW_OTHER);
        flowBean1.setDateTime(TimeUtils.getNowString());
        flowBean1.setBodyJson(json);
//        LocalLogUtil.temp2File("----：", flowBean1.toString());

        getDaoSession().getFlowBeanDao().insert(flowBean1);
        return new UpdateResult(bookBeans.size());
    }

    public UpdateResult removeOld(String json, List<BookBean> bookBeans) {
        updateBook2DB(bookBeans);
        FlowBean flowBean1 = new FlowBean();
        flowBean1.setUserId((Integer) ACache.getInstance().getAsObject(AKey.CACHE_USER_STAFF_ID));
        flowBean1.setFlowType(FlowType.FLOW_REMOVE);
        flowBean1.setDateTime(TimeUtils.getNowString());
        flowBean1.setBodyJson(json);
//        LocalLogUtil.temp2File("剔旧：", flowBean1.toString());
        getDaoSession().getFlowBeanDao().insert(flowBean1);
        return new UpdateResult(bookBeans.size());
    }

    public UpdateResult cacheFirstBook(String parseJson, List<ShelfBean> shelfBeans) {
        updateShelf2DB(shelfBeans);
        FlowBean flowBean1 = new FlowBean();
        flowBean1.setUserId((Integer) ACache.getInstance().getAsObject(AKey.CACHE_USER_STAFF_ID));
        flowBean1.setFlowType(FlowType.FLOW_FIRST);
        flowBean1.setDateTime(TimeUtils.getNowString());
        flowBean1.setBodyJson(parseJson);
        getDaoSession().getFlowBeanDao().insert(flowBean1);
        return new UpdateResult(shelfBeans.size());
    }

    public UpdateResult cacheupdatetask(String parseJson) {
        FlowBean flowBean1 = new FlowBean();
        flowBean1.setUserId((Integer) ACache.getInstance().getAsObject(AKey.CACHE_USER_STAFF_ID));
        flowBean1.setFlowType(FlowType.FLOW_FIRST_TASK);
        flowBean1.setDateTime(TimeUtils.getNowString());
        flowBean1.setBodyJson(parseJson);
//        LocalLogUtil.temp2File("首书更新：", flowBean1.toString());
        getDaoSession().getFlowBeanDao().insert(flowBean1);
        return new UpdateResult(1);
    }

    public UpdateResult cacheListGuide(String parseJson, List<BookBean> beans) {
        updateBook2DB(beans);
        FlowBean flowBean1 = new FlowBean();
        flowBean1.setUserId((Integer) ACache.getInstance().getAsObject(AKey.CACHE_USER_STAFF_ID));
        flowBean1.setFlowType(FlowType.FLOW_LISTING_GUIDE);
        flowBean1.setDateTime(TimeUtils.getNowString());
        flowBean1.setBodyJson(parseJson);
//        LocalLogUtil.temp2File("上架指导：", flowBean1.toString());
        getDaoSession().getFlowBeanDao().insert(flowBean1);
        return new UpdateResult(beans.size());
    }

    public UpdateResult changeShelf(String json, List<BookBean> bookBeans) {
        updateBook2DB(bookBeans);
        FlowBean flowBean1 = new FlowBean();
        flowBean1.setUserId((Integer) ACache.getInstance().getAsObject(AKey.CACHE_USER_STAFF_ID));
        flowBean1.setFlowType(FlowType.FLOW_CHANGE);
        flowBean1.setDateTime(TimeUtils.getNowString());
        flowBean1.setBodyJson(json);
//        LocalLogUtil.temp2File("倒架：", flowBean1.toString());
        getDaoSession().getFlowBeanDao().insert(flowBean1);
        return new UpdateResult(bookBeans.size());
    }

    public UpdateResult changeShelfLog(String json) {
        FlowBean flowBean1 = new FlowBean();
        flowBean1.setUserId((Integer) ACache.getInstance().getAsObject(AKey.CACHE_USER_STAFF_ID));
        flowBean1.setFlowType(FlowType.FLOW_CHANGE_LOG);
        flowBean1.setDateTime(TimeUtils.getNowString());
        flowBean1.setBodyJson(json);
//        LocalLogUtil.temp2File("倒架Log：", flowBean1.toString());

        getDaoSession().getFlowBeanDao().insert(flowBean1);
        return new UpdateResult(1);
    }


    public Integer getBusinessCount() {
        List<FlowBean> flowBeans = getDaoSession().getFlowBeanDao().loadAll();
        if (flowBeans == null)
            return 0;
        return flowBeans.size();
    }


    public BookCarBean getBookCarbyId(String carId) {
        return getDaoSession().getBookCarBeanDao().queryBuilder().where(BookCarBeanDao.Properties.CarId.eq(carId)).unique();
    }

    public UpdateResult bindBook2Car(List<BookBean> beans, String carId) {
        String booids = StreamSupport.stream(beans).map(BookBean::getBarCode).reduce("", (s, s2) -> TextUtils.isEmpty(s) ? s + s2 : s + ";" + s2);
        BookCarBean bookCar = getBookCarbyId(carId);
        if (bookCar == null)
            return new UpdateResult(0);
        bookCar.setBookIds(booids);
        getDaoSession().getBookCarBeanDao().update(bookCar);
        return new UpdateResult(beans.size());
    }

    public UpdateResult upBook2ShelfFromCar(List<BookBean> beans, String carId) {
        String booids = StreamSupport.stream(beans).map(BookBean::getBarCode).reduce("", (s, s2) -> TextUtils.isEmpty(s) ? s + s2 : s + ";" + s2);
        BookCarBean bookCar = getBookCarbyId(carId);
        if (bookCar == null)
            return new UpdateResult(0);
        String newBookIds = J8Arrays.stream(bookCar.getBookIds().split(";"))
                .filter(s -> !booids.contains(s))
                .reduce("", (s, s2) -> TextUtils.isEmpty(s) ? s + s2 : s + ";" + s2);
        bookCar.setBookIds(newBookIds);
        getDaoSession().getBookCarBeanDao().update(bookCar);
        return new UpdateResult(beans.size());
    }

    public void removeAllCar() {
        getDaoSession().getBookCarBeanDao().deleteAll();
    }

    /**
     * @param startcode
     * @param endcode
     * @return 1. > : gt
     * 2. < : lt
     * 3. >= : ge
     * 4. <= : le
     */
    public List<ShelfBean> getShelfBetween(String startcode, String endcode) {
        ShelfBean startExtend = getDaoSession().getShelfBeanDao().queryBuilder().where(
                        getDaoSession().getShelfBeanDao().queryBuilder().and(
                                ShelfBeanDao.Properties.PretendIndexNum.isNotNull(),
                                ShelfBeanDao.Properties.ShelfCode.le(startcode)
                        )
                )
                .orderDesc(ShelfBeanDao.Properties.PretendIndexNum)
                .limit(1)
                .unique();
        ShelfBean endExtend = getDaoSession().getShelfBeanDao().queryBuilder().where(
                        getDaoSession().getShelfBeanDao().queryBuilder().and(
                                ShelfBeanDao.Properties.PretendIndexNum.isNotNull(),
                                ShelfBeanDao.Properties.ShelfCode.ge(endcode)
                        )
                )
                .orderAsc(ShelfBeanDao.Properties.PretendIndexNum)
                .limit(1)
                .unique();
        if (startExtend != null && startExtend.getShelfCode() != null) {
            startcode = startExtend.getShelfCode();
            KLog.e("拓展开始节点： " + startExtend.getShelfName() + "  " + startExtend.getShelfCode());
        }
        if (endExtend != null && endExtend.getShelfCode() != null) {
            endcode = endExtend.getShelfCode();
            KLog.e("拓展结束节点： " + endExtend.getShelfName() + "  " + endExtend.getShelfCode());
        }
        return getDaoSession().getShelfBeanDao().queryBuilder().where(ShelfBeanDao.Properties.ShelfCode.between(startcode, endcode), ShelfBeanDao.Properties.PretendIndexNum.isNotNull()).orderAsc(ShelfBeanDao.Properties.ShelfCode).list();
    }

    public List<FlowBean> getbusinessData() {
        return getDaoSession().getFlowBeanDao().queryBuilder().list();
    }

    public void deleteBusinessBean(FlowBean bean) {
        getDaoSession().getFlowBeanDao().delete(bean);
    }

    public void cleanBusinessData() {
        getDaoSession().getFlowBeanDao().deleteAll();
    }

    public List<FlowBean> getFirstTaskBean(int finishstatus, int pageindex, int pagesize) {
        if (finishstatus == 1)
            return new ArrayList<>();
        return getDaoSession().getFlowBeanDao().queryBuilder().where(FlowBeanDao.Properties.FlowType.eq(FlowType.FLOW_FIRST_TASK)).list();
    }

    public void saveStruct2DB(List<StructBean> collect) {
        getDaoSession().getStructBeanDao().insertOrReplaceInTx(collect);
    }

    public void doTest() {
        List<ColumBean> columBeans = getDaoSession().getColumBeanDao().loadAll();
        for (ColumBean columBean : columBeans) {
            System.out.print("  ColumName() = " + columBean.getColumName());
            System.out.print("  ColumSortName() = " + columBean.getColumSortName());
            System.out.println("  shelfBean = " + columBean.getShelfBeans().size());
        }
        long start = System.currentTimeMillis();
        StructBean bean = getDaoSession().getStructBeanDao().queryBuilder().where(StructBeanDao.Properties.RoomName.eq("5楼北区")).unique();
    }

    public void cleanAllStruct() {
        getDaoSession().getStructBeanDao().deleteAll();
    }

    public List<StructBean> getAllStruct() {
        return getDaoSession().getStructBeanDao().queryBuilder().list();
    }

    public void insertCoumBneas(List<ColumBean> columBeans) {
        try {
            getDaoSession().runInTx(() -> getDaoSession().getColumBeanDao().insertInTx(columBeans));
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public void removeAllColum() {
        getDaoSession().getColumBeanDao().deleteAll();
    }

    public List<ColumBean> getColumData(StructBean bean) {
        String keywordPattern = bean.getBuildingName() + bean.getFloorName() + bean.getRoomName() + "%";
        return getDaoSession().getColumBeanDao().queryBuilder().where(ColumBeanDao.Properties.ColumName.like(keywordPattern)).orderAsc(ColumBeanDao.Properties.ColumNum).list();
    }

    public StructBean getStructByShelf(ShelfBean bean) {
        return getDaoSession().getStructBeanDao().queryBuilder()
                .where(StructBeanDao.Properties.BuildingName.eq(bean.getBuildingName()),
                        StructBeanDao.Properties.FloorName.eq(bean.getFloorName()),
                        StructBeanDao.Properties.RoomName.eq(bean.getRoomName())).unique();
    }

    public List<BookBean> getBookByMultiShelf(String startCode, String endCode) {
        return getDaoSession().getBookBeanDao().queryBuilder().where(BookBeanDao.Properties.ShelfCode.between(startCode, endCode)).list();
    }

    public int getBookCount(String startCode, String endCode) {
        String sql = "SELECT COUNT(*) FROM BOOK_BEAN WHERE SHELF_CODE BETWEEN ? AND ?";
        Cursor c = daoSession.getDatabase().rawQuery(sql, new String[]{startCode, endCode});
        int count = 0;
        try {
            if (c != null) {
                if (c.moveToFirst()) {
                    do {
                        count = c.getInt(0);
                    } while (c.moveToNext());
                }
            }
        } finally {
            if (c != null) {
                c.close();
            }
        }
        return count;
    }

    /**
     * 根据图书的伪索书号查应该在哪个原始层位
     *
     * @param pretendCallNo
     * @return 1. > : gt
     * 2. < : lt
     * 3. >= : ge
     * 4. <= : le
     */


    public ShelfBean getshelfbyPretendIndexNum(String pretendCallNo) {
        KLog.e("开始查询 " + pretendCallNo);
        long l = System.currentTimeMillis();
        List<ShelfBean> list = getDaoSession().getShelfBeanDao().queryBuilder().where(
                        getDaoSession().getShelfBeanDao().queryBuilder().and(
                                ShelfBeanDao.Properties.PretendIndexNum.isNotNull(),
                                ShelfBeanDao.Properties.PretendIndexNum.le(pretendCallNo)
                        )
                ).orderDesc(ShelfBeanDao.Properties.PretendIndexNum)
                .limit(1)
                .list();
        KLog.e("查询时间： " + (System.currentTimeMillis() - l));
        if (list != null && !list.isEmpty()) {
            return list.get(list.size() - 1);
        }
        return null;
    }

    public Long getAllColum() {
        return   getDaoSession().getColumBeanDao().queryBuilder().count();
    }
}
